#include "ColorPlane.h"

ColorPlane::ColorPlane()
{
	Plane = NULL;
}
ColorPlane::ColorPlane(int H, int W, int Deep)
{
	create(H,W,Deep);
}
ColorPlane::ColorPlane(ColorPlane& a)
{
	create(a.H,a.W,a.Deep);
	operator=(a);
}
void ColorPlane::create(int H, int W, int Deep = 24)
{
	Plane = new double[H*W];
	this->Deep = Deep;
	this->H = H;
	this->W = W;
	H_in = H;
	W_in = W;

}
ColorPlane& ColorPlane::operator = (ColorPlane* Second)
{
	if (Plane == NULL)
		Plane = new double[Second->GetSize()];
	else
	{
		delete Plane;
		create(Second->GetH(),Second->GetW());
	}
	for (int i = 0; i < H; i++)
		for (int j = 0; j < W; j++)
		{
			double temp = Second->
				GetPixel(i,j);
			* (Plane + i*W + j) = temp;
		}
	Deep = Second->Deep;
	H_in = H;
	W_in = W;
	return *this;
}


ColorPlane* ColorPlane::operator + (ColorPlane* Second)
{
	ColorPlane* Sum;
	Sum = new ColorPlane;
	
	double temp;
	int H_ = 0;
	int W_ = 0;

			if (H >  Second->H)
			H_ = Second->H;
			else H_ = H;
			if (W >  Second->W)
			W_ = Second->W;
			else W_ = W;
	Sum->create(H_,W_,Deep);
	for (int i = 0; i < H_; i++)
		for (int j = 0; j < W_; j++)
		{	
 			temp = (* (Plane + i*W + j) + Second->GetPixel(i,j));
			Sum->SetPixel(i,j, temp);
		}

	return Sum;

}
ColorPlane* ColorPlane::operator - (ColorPlane* Second)
{
	ColorPlane* dif;
	dif = new ColorPlane;
	dif->create(H,W,Deep);
	double temp;
	for (int i = 0; i < H; i++)
		for (int j = 0; i < W; i++)
		{
			temp = (* (Plane + i*W + j) - Second->GetPixel(i,j));
			if (temp < 0) 
			dif->SetPixel(i,j,0);
			else dif->SetPixel(i,j,temp);
		}

		return dif;

}
ColorPlane* ColorPlane::operator * (ColorPlane* Second)
{
	ColorPlane* Mul;
	Mul = new ColorPlane;

	double temp;
	int H_ = 0;
	int W_ = 0;

			if (H >  Second->H)
			H_ = Second->H;
			else H_ = H;
			if (W >  Second->W)
			W_ = Second->W;
			else W_ = W;
	Mul->create(H_,W_,Deep);
	for (int i = 0; i < H_; i++)
		for (int j = 0; j < W_; j++)
		{	
			temp = (* (Plane + i*W + j) * Second->GetPixel(i,j));
			Mul->SetPixel(i,j, temp);
		}

		return Mul;

}
void ColorPlane::mult(double number)
{

	double temp;
	for (int i = 0; i < H; i++)
		for (int j = 0; j < W; j++)
		{	
			temp = *(Plane + i*W + j);
			temp *= number;
			*(Plane + i*W + j) = temp;
		}
}

void ColorPlane::summ(double number)
{
	double temp;
	for (int i = 0; i < H; i++)
		for (int j = 0; j < W; j++)
		{	
			temp = *(Plane + i*W + j);
			temp += number;
			*(Plane + i*W + j) = temp;
		}
}
void ColorPlane::SetArea(int H,int W)
{
	H_in = H;
	W_in = W;
}

double ColorPlane::GetPixel(int x,int y)
{
	return *(Plane + x*W + y);
}
double ColorPlane::GetPixel(int i)
{
	return *(Plane + i);
}


double * ColorPlane::GetPlaneAdress()
{
	return Plane;
}
void ColorPlane::SetPixel(int x, int y, double temp)
{
	*(Plane + x*W + y) = temp;
}
void ColorPlane::SetPixel(int i , double temp)
{
	*(Plane + i) = temp;
}


int ColorPlane::GetSize()
{
	return H*W;
}
int ColorPlane::GetW()
{
	return W;
}


int ColorPlane::GetH()
{
	return H;
}
double ColorPlane::GetAvr()
{
	double sum = 0;
	int size = H*W;
	for(int i = 0; i <size; i++ )
	{
		sum+=Plane[i];
	}
	return sum/size;
}
void ColorPlane::SetToConst(double a)
{
	int size = H*W;
	for (int i =0; i< size; i++)
	{
		Plane[i] = a;
	}
}
//void ColorPlane::Neg()
//{
//	CImageGradation::PlaneNeg(this);	
//}
//void ColorPlane::Convolution(CMask * mask)
//{
//	double temp = 0;
//	double aver = AvaerageBr();
//	double * Plane1 = new double[H*W];
//	int Hm = mask->GetX() / 2;
//	int Wm = mask->GetY() / 2;
//	int qm = 0, km =  0;
//	/*switch (mask->size)
//	{
//		case 0:
//		{
//			for (int i = Hm; i < H - Hm; i++)
//			for (int j = Wm; j < W - Wm; j++)
//			{
//				temp = 0;
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						temp += *(Plane + (i*W + k) + (j)) * mask->GetValue(0,km);
//						km++;
//					}
//				*(Plane1 + (i*W) + (j)) = fabs(temp);
//			}
//			break;
//		}
//		case 1:
//		{
//			for (int i = Hm; i < H - Hm; i++)
//			for (int j = Wm; j < W - Wm; j++)
//			{
//				temp = 0;
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						temp += *(Plane + (i*W) + (j + k)) * mask->GetValue(km,0);
//						km++;
//					}
//				*(Plane1 + (i*W) + (j)) = fabs(temp);
//			}
//			break;
//		}
//		case 2:
//		{*/
//			for (int i = 0; i < H; i++)
//			for (int j = 0; j < W; j++)
//			{
//				temp = 0;
//				for (int q = - Hm; q < Hm + 1; q++)
//				{
//					km = 0;
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						if (i + q < 0|| j + k < 0||i+q>=H||j+k>=W)
//						{
//							aver = *(Plane + (i*W) + (j));
//							temp += aver*mask->GetValue(qm,km);
//						} else
//						temp += *(Plane + (i*W + q) + (j + k)) * mask->GetValue(qm,km);
//						km++;
//					}
//					qm++;
//				}
//				qm = 0;
//				*(Plane1 + (i*W) + (j)) = fabs(temp);
//			}
//
//		
//
//	
//	for (int i = 0; i < H*W; i++)
//	{
//		*(Plane + i) = *(Plane1+i);
//
//	}
//	delete[] Plane1;
//}
//void ColorPlane::Convolution_min(int size)
//{
//	double temp, temp_1 = 0;
//	double aver =  AvaerageBr();
//	double * Plane1 = new double[H*W];
//	int Hm = size / 2;
//	int Wm = size / 2;
//	int qm = 0, km =  0;
//	/*switch (mask->size)
//	{
//		case 0:
//		{
//			for (int i = Hm; i < H - Hm; i++)
//			for (int j = Wm; j < W - Wm; j++)
//			{
//				temp = 0;
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						temp += *(Plane + (i*W + k) + (j)) * mask->GetValue(0,km);
//						km++;
//					}
//				*(Plane1 + (i*W) + (j)) = fabs(temp);
//			}
//			break;
//		}
//		case 1:
//		{
//			for (int i = Hm; i < H - Hm; i++)
//			for (int j = Wm; j < W - Wm; j++)
//			{
//				temp = 0;
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						temp += *(Plane + (i*W) + (j + k)) * mask->GetValue(km,0);
//						km++;
//					}
//				*(Plane1 + (i*W) + (j)) = fabs(temp);
//			}
//			break;
//		}
//		case 2:
//		{*/
//			for (int i = 0; i < H; i++)
//			for (int j = 0; j < W; j++)
//			{
//				temp = 1;
//				for (int q = - Hm; q < Hm + 1; q++)
//				{
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						if (i + q < 0|| j + k < 0||i+q>=H||j+k>=W)
//						{
//							aver = *(Plane + (i*W) + (j));
//							temp_1 = aver;
//						} else		
//							temp_1 = *(Plane + ((i+q)*W) + (j+k));
//						if (temp > temp_1)
//						{
//							temp = temp_1;
//						}
//
//					}
//				}
//				*(Plane1 + (i*W) + (j)) = temp;
//			}
//
//		
//
//	
//	for (int i = 0; i < H*W; i++)
//	{
//		*(Plane + i) = *(Plane1+i);
//
//	}
//	delete[] Plane1;
//}
//void ColorPlane::Convolution_max(int size)
//{
//	double temp = 0, temp_1 = 0;
//	double aver =  AvaerageBr();
//	double * Plane1 = new double[H*W];
//	int Hm = size / 2;
//	int Wm = size / 2;
//	int qm = 0, km =  0;
//	/*switch (mask->size)
//	{
//		case 0:
//		{
//			for (int i = Hm; i < H - Hm; i++)
//			for (int j = Wm; j < W - Wm; j++)
//			{
//				temp = 0;
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						temp += *(Plane + (i*W + k) + (j)) * mask->GetValue(0,km);
//						km++;
//					}
//				*(Plane1 + (i*W) + (j)) = fabs(temp);
//			}
//			break;
//		}
//		case 1:
//		{
//			for (int i = Hm; i < H - Hm; i++)
//			for (int j = Wm; j < W - Wm; j++)
//			{
//				temp = 0;
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						temp += *(Plane + (i*W) + (j + k)) * mask->GetValue(km,0);
//						km++;
//					}
//				*(Plane1 + (i*W) + (j)) = fabs(temp);
//			}
//			break;
//		}
//		case 2:
//		{*/
//			for (int i = 0; i < H; i++)
//			for (int j = 0; j < W; j++)
//			{
//				temp = 0;
//				for (int q = - Hm; q < Hm + 1; q++)
//				{
//					for (int k = -Wm; k < Wm + 1; k++)
//					{
//						if (i + q < 0|| j + k < 0||i+q>=H||j+k>=W)
//						{
//							aver = *(Plane + (i*W) + (j));
//							temp_1 = aver;
//						} else		
//							temp_1 = *(Plane + ((i+q)*W) + (j+k));
//						if (temp < temp_1)
//						{
//							temp = temp_1;
//						}
//
//					}
//				}
//				*(Plane1 + (i*W) + (j)) = temp;
//			}
//
//		
//
//	
//	for (int i = 0; i < H*W; i++)
//	{
//		*(Plane + i) = *(Plane1+i);
//
//	}
//	delete[] Plane1;
//}
//void ColorPlane::Convolution_med_cross(int size)
//{
//	double temp,temp_next, temp_1 = 0;
//	double aver =  AvaerageBr();
//	double * Plane1 = new double[H*W];
//	int Hm = size / 2;
//	int Wm = size / 2;
//	double* sort = new double[size*2 - 1];
//
//	int i_sort = 0;
//	int qm = 0, km =  0;
//		
//	for (int i = 0; i < H ; i++)
//	for (int j = 0; j < W; j++)
//	{
//		i_sort= 0;
//		for (int q = - Hm; q < Hm + 1; q++)
//		{
//			if (i + q < 0 || i + q>=H)
//			{
//				sort[i_sort] = *(Plane + ((i)*W) + (j));							
//			} else
//				sort[i_sort] = *(Plane + ((i+q)*W) + (j));
//			i_sort++;
//		}			
//		for (int k = -Wm; k < Wm + 1; k++)
//		{
//			if (i != j+k)
//			{		
//				if ( j + k < 0||j+k>=W)
//				{
//					sort[i_sort] = *(Plane + (i*W) + (j));							
//				} else
//					sort[i_sort] = *(Plane + (i*W) + (j+k));
//				i_sort++;
//			}
//
//		}
//		temp = 2;
//		temp_next = 0;
//		for (int q = 0; q < size*2 -1; q++)
//		{
//			temp = 2;
//			for (int k = q; k < size*2 -1; k++)
//			{
//				if (sort[k] < temp && sort[k] >= temp_next)
//				{
//					temp = sort[k];
//					i_sort = k;
//				}
//
//			}
//			temp_1 = sort[q];
//			sort[i_sort] = sort[q];
//			sort[q] = temp_1;
//			temp_next = temp;
//
//		}
//		*(Plane1 + (i*W) + (j)) = sort[size];
//	}
//
//	for (int i = 0; i< size*2 - 1; i++)
//	{
//		sort[i] = 1;
//	}
//	for (int i = 0; i < H*W; i++)
//	{
//		*(Plane + i) = *(Plane1+i);
//
//	}
//	delete[] Plane1;
//}
//void ColorPlane::Convolution_med_square(int size)
//{
//	double temp,temp_next, temp_1 = 0;
//	double aver =  AvaerageBr();
//	double * Plane1 = new double[H*W];
//	int Hm = size / 2;
//	int Wm = size / 2;
//	double* sort = new double [size*size];
//	int size_sort = 0;
//	int i_sort = 0;
//	int qm = 0, km =  0;
//		
//	for (int i = 0; i < H; i++)
//	for (int j = 0; j < W; j++)
//	{
//		i_sort= 0;
//		for (int q = - Hm; q < Hm; q++)
//		{
//			for (int k = -Wm; k < Wm; k++)
//			{
//
//				if (i + q < 0|| j + k < 0||i+q>=H||j+k>=W)
//				{
//					sort[i_sort] = *(Plane + (i*W) + (j));							
//				} else
//					sort[i_sort] = *(Plane + (i*W) + (j+k));
//					i_sort++;
//			}
//		}			
//		size_sort = i_sort;
//		temp = 1;
//		temp_next = 0;
//		for (int q = 0; q < size_sort; q++)
//		{
//			temp = 1;
//			for (int k = q; k < size_sort; k++)
//			{
//				if (sort[k] < temp && sort[k] >= temp_next)
//				{
//					temp = sort[k];
//					i_sort = k;
//				}
//
//			}
//			temp_1 = sort[q];
//			sort[i_sort] = sort[q];
//			sort[q] = temp_1;
//			temp_next = temp;
//
//		}
//		*(Plane1 + (i*W) + (j)) = sort[size_sort/2];
//	}
//
//	for (int i = 0; i < H*W; i++)
//	{
//		*(Plane + i) = *(Plane1+i);
//
//	}
//	delete[] Plane1;
//}
//void ColorPlane::Convolution_med_round(int size)
//{
//	double temp,temp_next, temp_1 = 0;
//	double * Plane1 = new double[H*W];
//	int Hm = size / 2;
//	int Wm = size / 2;
//	double* sort = new double [size*size];
//	int size_sort = 0;
//	int i_sort = 0;
//	int qm = 0, km =  0;
//
//	for (int i = 0; i < H; i++)
//		for (int j = 0; j < W; j++)
//		{
//			i_sort= 0;
//			for (int q = - Hm; q < Hm; q++)
//			{
//				for (int k = -Wm; k < Wm; k++)
//				{
//					
//					if (pow((double)k*k + (double)q*q,0.5)<= Hm)
//					{					
//					if (i + q < 0|| j + k < 0||i+q>=H||j+k>=W)
//					{
//						sort[i_sort] = *(Plane + (i*W) + (j));							
//					} else
//						sort[i_sort] = *(Plane + (i*W) + (j+k));
//					i_sort++;
//					}
//
//				}
//			}			
//			size_sort = i_sort;
//			temp = 1;
//			temp_next = 0;
//			for (int q = 0; q < size_sort; q++)
//			{
//				temp = 1;
//				for (int k = q; k < size_sort; k++)
//				{
//					if (sort[k] < temp && sort[k] >= temp_next)
//					{
//						temp = sort[k];
//						i_sort = k;
//					}
//
//				}
//				temp_1 = sort[q];
//				sort[i_sort] = sort[q];
//				sort[q] = temp_1;
//				temp_next = temp;
//
//			}
//			*(Plane1 + (i*W) + (j)) = sort[size_sort/2];
//		}
//
//		for (int i = 0; i < H*W; i++)
//		{
//			*(Plane + i) = *(Plane1+i);
//
//		}
//		delete[] Plane1;
//
//}
double ColorPlane::AvaerageBr()
{
	double summ = 0;
	for (int j = 0; j < W*H; j++)
		summ += *(Plane + j);
	summ /= W*H;
	return summ;
}
double ColorPlane::findClosest(double temp)
{
	for (int i = 0; i < W*H; i++)
	{
		if (fabs(Plane[i] - temp)<= 0.001)
		return Plane[i];
	}
}
void ColorPlane::Potent()
{
  	for (int i = 0 ; i < H * W; i ++)
	{
		double temp = 0;
		temp=Plane[i];
		Plane[i] = pow(2.718281828,temp);
		Plane[i] /= 4;
	}
}
ColorPlane::~ColorPlane()
{
	delete [] Plane;
}

